#include <bits/stdc++.h>
using namespace std;
struct node{
    int d,v,a;
    bool vmax;
    float xv;
};
int T,n,m,l,v;
int zh(float t)
{
    float u=t;
    while(u>=1.0)
    {
        while(u>=1000000.0)
            u-=1000000.0;
        while(u>=100000.0)
            u-=100000.0;
        while(u>=10000.0)
            u-=10000.0;
        while(u>=1000.0)
            u-=1000.0;
        while(u>=100.0)
            u-=100.0;
        while(u>=10.0)
            u-=10.0;
        u--;
    }
    if(u==0)
        return (int)t;
    return (int)t+1;
}
float ax(int d,int v0,int a,int v)
{
    if((v0>v&&a>=0)||(v0==v&&a>0))//ok
        return (float)d;//(except)d right all
    if(v0<=v&&a<=0)
        return -1.0;//never ok
    if(v0<=v&&a>0)//ok
    {
        float tmp=(float)d+((float)v*(float)v-(float)v0*(float)v0)/(2.0*(float)a);
        if(tmp>float(l))
            return -1.0;//never ok
        else
            return tmp;//tmp right all
    }
    if(v0>v&&a<0)
    {
        float tmp=(float)d+((float)v*(float)v-(float)v0*(float)v0)/(2.0*(float)a);
        if(tmp>float(l))
            return float(l)+1.0;//d right all
        else
            return tmp;//d tmp
    }
}
inline void solve()
{
    node car[100001];
    int p[100001],pnum[100001],sum=0,ans=0,maxp=0,as;
    memset(pnum,0,sizeof(pnum));
    cin>>n>>m>>l>>v;
    for(int i=1;i<=n;i++)
    {
        cin>>car[i].d>>car[i].v>>car[i].a;
        car[i].vmax=0;
        as+=car[i].a;
        car[i].xv=ax(car[i].d,car[i].v,car[i].a,v);
    }
    for(int i=1;i<=m;i++)
        cin>>p[i];
    sort(p+1,p+m+1);
    if(as==0)
        for(int i=1;i<=n;i++)
            if(car[i].v>v)
            {
                int ad=lower_bound(p+1,p+m,car[i].d)-p;
                if(car[i].d>p[ad])
                    continue;
                car[i].vmax=1;
                for(int j=ad;j<=m;j++)
                    pnum[p[j]]++;
            }
    else
    {
        for(int i=1;i<=m;i++)
        {
            if(car[i].xv==-1)
                continue;
            else if(((car[i].v>v&&car[i].a>=0)||(car[i].v==v&&car[i].a>0))||(car[i].v<=v&&car[i].a>0))
            {
                int k=zh(car[i].xv);
                if(car[i].v==v)
                    k++;
                int ad=lower_bound(p+1,p+m,k)-p;
                if(ad<m)
                {
                    car[i].vmax=1;
                    for(int j=ad;j<=m;j++)
                        pnum[p[j]]++;
                }
                else
                {
                    if(k<=p[m])
                    {
                        car[i].vmax=1;
                        pnum[p[m]]++;
                    }
                    else
                        continue;
                }
            }
            else if(car[i].v>v&&car[i].a<0)
            {
                int ad1=lower_bound(p+1,p+m,car[i].d)-p,ad2=lower_bound(p+1,p+m,(int)car[i].xv)-p;
                if(ad1==ad2)
                    if(car[i].d<=p[ad1]&&(int)car[i].xv>p[ad1])
                    {
                        car[i].vmax=1;
                        pnum[p[ad1]]++;
                    }
                else
                {
                    car[i].vmax=1;
                    for(int j=ad1;j<=ad2;j++)
                        pnum[p[j]]++;
                }
            }
        }

    }
    for(int i=1;i<=n;i++)
        if(car[i].vmax==1)
               sum++;
    cout<<sum<<" ";
    for(int i=1;i<=m;i++)
    {
        if(pnum[i]>maxp)
        {
            ans=1;
            maxp=pnum[i];
        }
        else if(pnum[i]==maxp)
            ans++;
    }
    cout<<m-ans<<endl;
}
int main()
{
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>T;
    while(T--)
        solve();
    return 0;
}
